/**********************************************************
        线程管理头文件krlthread_t.h
***********************************************************
                彭东
**********************************************************/
#ifndef _KRLTHREAD_T_H
#define _KRLTHREAD_T_H
#define TDSTUS_RUN 0   // 运行
#define TDSTUS_SLEEP 3 // 睡眠
#define TDSTUS_WAIT 4  // 等待
#define TDSTUS_NEW 5   // 新建
#define TDSTUS_ZOMB 6  // 死亡

#define TDFLAG_FREE (1)
#define TDFLAG_BUSY (2)

#define TDRUN_TICK 20

#define PRITY_MAX 64
#define PRITY_MIN 0
#define PRILG_SYS 0
#define PRILG_USR 5

#define MICRSTK_MAX 4

#define THREAD_MAX (4)

#define KERNTHREAD_FLG 0
#define USERTHREAD_FLG 3

#if ((defined CFG_X86_PLATFORM))
#define DAFT_TDUSRSTKSZ 0x8000
#define DAFT_TDKRLSTKSZ 0x8000
#endif

#if ((defined CFG_X86_PLATFORM))
#define TD_HAND_MAX 8
#define DAFT_SPSR 0x10
#define DAFT_CPSR 0xd3
#define DAFT_CIDLESPSR 0x13
#endif

#define K_CS_IDX 0x08
#define K_DS_IDX 0x10
#define U_CS_IDX 0x1b
#define U_DS_IDX 0x23
#define K_TAR_IDX 0x28
#define UMOD_EFLAGS 0x1202
#define KMOD_EFLAGS 0x202

typedef struct s_MICRSTK
{
    uint_t msk_val[MICRSTK_MAX];
} micrstk_t;

// 机器上下文
typedef struct s_CONTEXT
{
    uint_t ctx_nextrip;    // rip，下一次运行地址
    uint_t ctx_nextrsp;    // rsp，下一个运行的内核栈地址
    x64tss_t *ctx_nexttss; // tss，指向 tss 结构
} context_t;

// 进程定义
typedef struct s_THREAD
{
    spinlock_t td_lock;    // 自旋锁
    list_h_t td_list;      // 进程列表
    uint_t td_flgs;        // 进程标志
    uint_t td_stus;        // 状态
    uint_t td_cpuid;       // cpu id
    uint_t td_id;          // 进程 id
    uint_t td_tick;        // 运行时间，tick 数
    uint_t td_privilege;   // 权限
    uint_t td_priority;    // 优先级
    uint_t td_runmode;     // 运行模式
    adr_t td_krlstktop;    // 内核栈顶
    adr_t td_krlstkstart;  // 内核栈底
    adr_t td_usrstktop;    // 用户栈顶
    adr_t td_usrstkstart;  // 用户栈底
    mmadrsdsc_t *td_mmdsc; // 地址空间结构
    void *td_resdsc;
    void *td_privtep;
    void *td_extdatap;
    context_t td_context;               // 机器上下文
    objnode_t *td_handtbl[TD_HAND_MAX]; // 打开对象数组，即 linux 下的 fd 数组
} thread_t;

#endif // KRLTHREAD_T_H
